﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.Windows.Forms;
using System.IO;
using System.Reflection;


namespace PacMan
{
    class Environment
    {
        public static int MinX = 0;
        public static int MaxX = 650;
        public static int MinY = 0;
        public static int MaxY = 650;
        public static string PlayerName;

        public static string GetFullFileName(string name) 
        {
            string fullName = Assembly.GetExecutingAssembly().Location;
            string dir = Path.GetDirectoryName(fullName);
            string fullFileName = Path.Combine(dir, name);
            return fullFileName;
        }
        
        public static RectangleF[] CreatePacDots(int amount,RectangleF[] obstacles)
        {
            RectangleF[] pacDots = new RectangleF[amount];
            Random rand = new Random();
            RectangleF pacdot = new RectangleF(rand.Next(50, Environment.MaxY), rand.Next(50, Environment.MaxX), 5, 5);
            for (int i = 0; i < pacDots.Length; i++)
            {
                while (IsAbleToCreateObject(pacDots, pacdot, i, 20) != true || IsAbleToCreateObject(obstacles, pacdot, obstacles.Length, 20)!=true)
                {
                    pacdot = new RectangleF(rand.Next(50, Environment.MaxY), rand.Next(50, Environment.MaxX), 8, 8);
                }
                pacDots[i] = pacdot;
            }
            return pacDots;
        }

        public static RectangleF[] GenerateMaze() 
        {
            RectangleF[] obstacles = new RectangleF[60];

            obstacles[0] = new RectangleF(0, 0, 650, 10);
            obstacles[5] = new RectangleF(650, 0, 10, 215);
            obstacles[6] = new RectangleF(0, 0, 10, 215);
            obstacles[20] = new RectangleF(0, 330, 10, 650);
            obstacles[16] = new RectangleF(510, 205, 140, 10);
            obstacles[17] = new RectangleF(510, 215, 10, 65);
            obstacles[18] = new RectangleF(510, 275, 140, 10);
            obstacles[56] = new RectangleF(510, 205, 140, 70);
            obstacles[19] = new RectangleF(650, 330, 10, 650);
            obstacles[21] = new RectangleF(0, 205, 150, 10);
            obstacles[22] = new RectangleF(140, 215, 10, 70);
            obstacles[23] = new RectangleF(0, 275, 150, 10);
            obstacles[54] = new RectangleF(0, 205, 150, 70);

            obstacles[9] = new RectangleF(55, 55, 95, 40);
            obstacles[2] = new RectangleF(195, 55, 80, 40);
            obstacles[1] = new RectangleF(320, 10, 20, 60);
            obstacles[3] = new RectangleF(385, 55, 80, 40);
            obstacles[4] = new RectangleF(510, 55, 95, 40);


            obstacles[15] = new RectangleF(55, 140, 95, 20);
            obstacles[10] = new RectangleF(195, 140, 20, 140);
            obstacles[7] = new RectangleF(260, 140, 140, 20);
            obstacles[8] = new RectangleF(315, 140, 30, 80);
            obstacles[12] = new RectangleF(445, 140, 20, 140);
            obstacles[14] = new RectangleF(510, 140, 95, 20);
            obstacles[11] = new RectangleF(215, 205, 50, 20);
            obstacles[13] = new RectangleF(390, 205, 55, 20);

            obstacles[24] = new RectangleF(0, 330, 150, 10);
            obstacles[25] = new RectangleF(140, 330, 10, 70);
            obstacles[26] = new RectangleF(0, 400, 150, 10);
            obstacles[53] = new RectangleF(0, 330, 150, 70);

            obstacles[27] = new RectangleF(510, 340, 10, 65);
            obstacles[28] = new RectangleF(510, 330, 140, 10);
            obstacles[29] = new RectangleF(510, 400, 140, 10);
            obstacles[55] = new RectangleF(510, 330, 140, 70);

            obstacles[30] = new RectangleF(10, 640, 800, 40);

            obstacles[31] = new RectangleF(260, 270, 140, 10);
            obstacles[32] = new RectangleF(260, 330, 140, 10);
            obstacles[33] = new RectangleF(260, 280, 10, 60);
            obstacles[34] = new RectangleF(390, 280, 10, 60);
            obstacles[57] = new RectangleF(260, 270, 140, 60);

            obstacles[35] = new RectangleF(195, 330, 20, 70);
            obstacles[36] = new RectangleF(445, 330, 20, 70);

            obstacles[37] = new RectangleF(260, 380, 140, 20);
            obstacles[38] = new RectangleF(320, 380, 20, 85);

            obstacles[39] = new RectangleF(260, 510, 140, 20);
            obstacles[40] = new RectangleF(320, 510, 20, 85);

            obstacles[41] = new RectangleF(195, 510, 20, 85);
            obstacles[42] = new RectangleF(445, 510, 20, 85);

            obstacles[43] = new RectangleF(55, 575, 220, 20);
            obstacles[44] = new RectangleF(385, 575, 220, 20);

            obstacles[46] = new RectangleF(385, 445, 80, 20);
            obstacles[47] = new RectangleF(195, 445, 80, 20);

            obstacles[45] = new RectangleF(510, 455, 85, 20);
            obstacles[48] = new RectangleF(510, 475, 20, 60);
            obstacles[49] = new RectangleF(585, 515, 65, 20);

            obstacles[50] = new RectangleF(55, 455, 90, 20);
            obstacles[51] = new RectangleF(125, 475, 20, 60);
            obstacles[52] = new RectangleF(10, 515, 65, 20);

            return obstacles;
        }
        
        public static RectangleF[] CreateObstacles(int amount)
        {
            RectangleF[] obstacles = new RectangleF[amount];
            Random rand = new Random();
            bool verticalObstacle = true;
            RectangleF obstacle = new RectangleF(rand.Next(0, Environment.MaxY - 150), rand.Next(0, Environment.MaxX - 150),
                                                  10, rand.Next(50, 150)); ;
            for (int i = 0; i < obstacles.Length; i++)
            {
                if (verticalObstacle)
                {
                    while (IsAbleToCreateObject(obstacles, obstacle, i, 75) != true)
                    {
                        obstacle = new RectangleF(rand.Next(0, Environment.MaxY - 150), rand.Next(0, Environment.MaxX - 150),
                                                      10, rand.Next(50, 150));
                    }
                    verticalObstacle = false;
                    obstacles[i] = obstacle;
                }
                else
                {
                    while (IsAbleToCreateObject(obstacles, obstacle, i, 75) != true)
                    {
                        obstacle = new RectangleF(rand.Next(0, Environment.MaxY - 150), rand.Next(0, Environment.MaxX - 150),
                                                          rand.Next(50, 150), 10);
                    }
                    verticalObstacle = true;
                    obstacles[i] = obstacle;
                }
            }
            return obstacles;
        }

        private static double FindDistance(float X1, float Y1, float X2, float Y2)
        {
            double distance;
            double betweenX = Math.Pow((X2 - X1), 2);
            double betweenY = Math.Pow((Y2 - Y1), 2);
            distance = betweenX + betweenY;
            return Math.Sqrt(distance);
        }

        public static bool IsAbleToCreateObject(RectangleF[] obstacles, RectangleF obstacle, int length, float restriction)
        {
            int index = 0;
           
            while (length != index)
            {
                if (obstacle.IntersectsWith(obstacles[index])) 
                {
                    return false;
                }
                if (FindDistance(obstacles[index].X, obstacles[index].Y, obstacle.X, obstacle.Y) < restriction)
                {
                    return false;
                }
                if (FindDistance(obstacles[index].Right, obstacles[index].Bottom, obstacle.Right, obstacle.Bottom) < restriction)
                {
                    return false;
                }
                if (FindDistance(obstacles[index].Right, obstacles[index].Bottom, obstacle.X, obstacle.Y) < restriction)
                {
                    return false;
                }
                if (FindDistance(obstacles[index].X, obstacles[index].Y, obstacle.Right, obstacle.Bottom) < restriction)
                {
                    return false;
                }
                index++;
            }
            return true;
        }

    }
}
